package com.webapp.api;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import com.webapp.helper.*;
import com.webapp.model.*;
import com.webapp.service.PayInfoService;
import com.webapp.view.BaseContants;
import org.hibernate.criterion.Order;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.webapp.api.unicom.SybPayService;
import com.webapp.api.unicom.SybUtil;
import com.webapp.service.OrderInfoService;
import com.webapp.service.UserInfoService;
import com.webapp.view.Resp;


@RestController
public class MecController extends BaseController{
	
	private static Logger LOGGER = LoggerFactory.getLogger(MecController.class);



//	public static final String BASE_URL = "http://ipms.csnits.com/ipms/service/"; //请求前置链接
	public static final String BASE_URL = "http://180.169.37.244/ipms/service/";
//	public static final String BASE_URL = "http://localhost:8080/ipms/service/";
	public static final String SELECT_ORDER_DETAIL = "S_SM_0108";//查询订单详情
	public static final String SELECT_ZJ_ORDER = "S_ZJOR_03";//闸机在停订单
	public static final String PAY_ROLE = "S_FM_0318";//获取计费规则
	public static final String BY_INFO_URL = "S_FM_0330"; //包月信息
	public static final String ALL_PARK_RECORD = "S_FM_0302"; // 获取所有停车记录
	public static final String PAY_CALL_BACK = "S_FM_0322";
	public static final String INVOICE_URL = "S_FM_0323";//获取发票
	public static final String BY_CALL_BACK = "S_FM_0331";//包月回调
	public static final String GET_COUPON_URL = "S_ZJCM_04"; //获取全部优惠券
	public static final String GET_COUPON_URL_ABLE = "S_ZJCM_05"; //获取可用优惠券
	private static final String GET_COUPON_MONEY_URL = "S_ZJCM_06";//查询待支付金额


	public static Map<String, Object> DATA_MAP = new ConcurrentHashMap<String, Object>() ;
	
	public static final String KEY_FILE = "/apps/key/rsa_private.key";
	
	private static final String LAKALA_API_URL_ = "https://s2.lakala.com/labs/txn/labs_order_pre_orderpay";
	private static final String LAKALA_ORDER_SELECT = "https://s2.lakala.com/labs/txn/labs_order_query";
	private static final String LAKALA_ORDER_DEL = "https://s2.lakala.com/labs/txn/labs_order_refund";
	
	private static final String LAKALA_MER_ID_ = "82229007523001M";//  82229007523004M
	private static final String LAKALA_APPID_ = "800000020015007";
	private static final String LAKALA_CLIENT_ID_ = "A8981474";  //     B7788106
	private static final String LAKALA_SERIAL_NO_ = "0096B57BFB264AE299"; //0096B57BFB264AE299


	@Autowired
	private UserInfoService userInfoService;
	@Autowired
	private OrderInfoService orderInfoService;
	@Autowired
	private PayInfoService payInfoService;

	/**
	 * 保存支付订单
	 * @param outNo
	 * @param cph
	 * @param orderNo
	 * @param streetNo
	 * @param times
	 * @param _type
	 * @param _month
	 * @param amount
	 */
	private void saveOrderInfo(String  outNo,String cph,String orderNo,String streetNo,String times,String _type,String _month,String amount,String orderNo2){
		try {
			OrderInfo order = orderInfoService.getByOutNo(outNo);
			if(order==null){
				order = orderInfoService.getByOrderNo2(orderNo2);
			}
			if(order==null) {
				order = new OrderInfo();
				order.setCph(cph);
				order.setCreateTime(new Date());
				order.setOutNo(outNo);
				order.setOrderNo(orderNo);
				order.setPay(String.valueOf(Double.parseDouble(amount)/100));
				order.setStreetNo(streetNo);
				order.setType(0);
				order.setMonth(times);
				order.setOrderNo2(orderNo2);
				if("GZ".equals(_type)) {
					order.setType(1);
					order.setMonth(_month);
				}
				orderInfoService.save(order);
			}else {
				order.setPay(String.valueOf(Double.parseDouble(amount)/100));
				order.setOutNo(outNo);
				order.setMonth(times);
				order.setOrderNo2(orderNo2);
				orderInfoService.update(order);
			}
		}catch (Exception e){
			e.printStackTrace();
		}
	}

	/**
	 * 发送交易记录
	 * @param _type
	 * @param orderNo2
	 * @param orderNo
	 * @param outNo
	 * @param times
	 * @param amount
	 */
	public void sendPayInfo(String _type,String orderNo2,String orderNo,String outNo,String times,String amount,String payMethod){
		if((StringUtil.isBlank(_type)||!"GZ".equals(_type))) {
			Map<String,Object> reqMap = new HashMap<>();
			Map<String,Object> reqAttrMap = new HashMap<>();
			reqAttrMap.put("tradeNo",orderNo2);
			reqAttrMap.put("orderNo",orderNo);
			reqAttrMap.put("outOrderNo",outNo);
			reqAttrMap.put("tradeOwner",payMethod);
			reqAttrMap.put("parkingTimes",times);
			reqAttrMap.put("orderMoney",String.valueOf(Double.valueOf(amount)/100));
			reqMap.put("attr",reqAttrMap);
			HttpUtils.postJson(BASE_URL+"S_FM_0317", JSONObject.toJSONString(reqMap));
		}
	}

	/**
	 * 获取闸机微信支付信息
	 *
	 * @param openid
	 * @param amount
	 * @param payMode
	 * @return
	 */
	@RequestMapping(path = "/data/getPayInfo")
	@ResponseBody
	public Resp getPayInfo(String openid, String amount, String payMode,String orderNo,String times,String streetNo,String _type,String _month,String cph) {
		Resp resp = new Resp(false);
		try {
			LOGGER.warn("支付下单:{},{},{},{},{},{},{}",streetNo,_type,openid,amount,payMode,orderNo,times,_month,cph);
			PayInfo payInfo = payInfoService.findByStreetNo(streetNo);
			Map<String, Object> dataMap = new HashMap<String, Object>();
			//通联
			if(payInfo!=null&&"allinpay".equals(payInfo.getPayMethod())) {
				SybPayService service = new SybPayService();
				String reqsn = String.valueOf(System.currentTimeMillis());//交易单号
				String random = SybUtil.getValidatecode(8);
				Map<String, String> map = service.pay(Long.valueOf(amount),
						reqsn,"W02","停车缴费","",openid,"30",
						BaseContants.PAY_NOTICE_WEBSITE+"/park/uninotice",
						"","","","",
						payInfo.getWechatAppId(),
						"", "", "",
						"", "", "","",
						random,payInfo.getAppId(),payInfo.getOrgId(),payInfo.getCusId(),payInfo.getRasStr());
				String orderNo2 = orderNo+"_"+random;
				if(map!=null) {
					String trxid = map.get("trxid");
//					DATA_MAP.put(trxid, trxid+"_"+_type+"_"+orderNo2+"_"+streetNo+"_"+_month+"_"+cph);
					sendPayInfo(_type,orderNo2,orderNo,trxid,times,amount,"allinpay");
					saveOrderInfo(trxid,cph,orderNo,streetNo,times,_type,_month,amount,orderNo2);
					dataMap.put("respData", JSONObject.parseObject(map.get("payinfo")));
					dataMap.put("cmdRetCode", "GLOBAL_SUCCESS");
					LOGGER.info("{}",JSONObject.toJSONString(dataMap));
					return new Resp(dataMap);
				}
			}else if(payInfo!=null&&"wechat".equals(payInfo.getPayMethod())){//微信直连支付
				Map<String,Object> respMap = WechatUtil.getWechatOrderId(amount,openid,"停车缴费",payInfo.getWechatAppId(),payInfo.getMchid(),payInfo.getWechatKey(),payInfo.getNoticeUrl(),payInfo.getSerialNo());
				if(respMap!=null){//成功下单
					String prepay_id = (String) respMap.get("prepay_id");
					String orderNo2 = (String)respMap.get("orderNo");
//					DATA_MAP.put(prepay_id, prepay_id+"_"+_type+"_"+orderNo2+"_"+streetNo+"_"+_month+"_"+cph);
					sendPayInfo(_type,orderNo2,orderNo,orderNo2,times,amount,"wechat");
					saveOrderInfo(prepay_id,cph,orderNo,streetNo,times,_type,_month,amount,orderNo2);
					dataMap.put("respData", respMap);
					dataMap.put("cmdRetCode", "GLOBAL_SUCCESS");
					LOGGER.info("{}",JSONObject.toJSONString(dataMap));
					return new Resp(dataMap);
				}
			}else {
				String appId =    payInfo.getLklAppId();//;
				String serialNo = payInfo.getSerialNo();
				String lakalamerid = payInfo.getMerId();
				String lakalaclientid = payInfo.getClientId();
				LakalaPayInfo l = new LakalaPayInfo();
				l.setAmount(amount);
				l.setAppId(payInfo.getWechatAppId());
				l.setMercId(lakalamerid);
				l.setOpenId(openid);
				String randomStr = StringUtil.getRandomString(8).toUpperCase();
				String orderNo2 = orderNo+"_"+randomStr;
				l.setOrderId(orderNo2);
				l.setPayMode(payMode);
				l.setSettleType("0");
				l.setSpbillCreateIp("127.0.0.1");
				l.setSubject("停车缴费");
				l.setTermNo(lakalaclientid);
				l.setTransType("51");
				l.setExterOrderSource("OS10000016");
				l.setExterMerOrderNo(orderNo2);
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("reqData", l);
				map.put("termExtInfo", new Object());
				String json = JSONObject.toJSONString(map);
				String timestamp = String.valueOf((int) (System.currentTimeMillis() / 1000));
				String nonce = StringUtil.generateString(12);
				String signature = sign(appId, serialNo, timestamp, nonce, json, "sit");
				String schema = "LKLAPI-SHA256withRSA-AES128";// 双向认证同时对body加密传输
				String token = "appid=\"" + appId + "\",serial_no=\"" + serialNo + "\",timestamp=\"" + timestamp
						+ "\",nonce_str=\"" + nonce + "\",signature=\"" + signature + "\"";
				String header = schema + " " + token;
				LOGGER.warn("拉卡拉订单 req:\n{}", json);
				String res = HttpUtils.postJsonWithHeader(LAKALA_API_URL_, json, header);
				JSONObject obj = JSONObject.parseObject(res);
				JSONObject obj2 = obj.getJSONObject("respData");
				String lklOrderId = obj2.getString("lklOrderId");
//				DATA_MAP.put(lklOrderId, lklOrderId+"_"+_type+"_"+orderNo2+"_"+streetNo+"_"+_month+"_"+cph);
				sendPayInfo(_type,orderNo2,orderNo,lklOrderId,times,amount,"lakala");
				saveOrderInfo(lklOrderId,cph,orderNo,streetNo,times,_type,_month,amount,orderNo2);
				return new Resp(obj);
			}
		} catch (Exception e) {
			LOGGER.error("e:{}", e);
		}
		return resp;
	}

	/**
	 * 公众号支付结果通知(壬通)
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/wechat/{streetNo}/notice")
	public Resp notice(HttpServletRequest request, @PathVariable(name = "streetNo")String streetNo) {
		Resp resp = new Resp(true);
		try {
			String json = getRequestJsonString(request);
			LOGGER.info("weapp msg:{}",json);
			JSONObject base = JSONObject.parseObject(json);
			JSONObject resource = base.getJSONObject("resource");
			String associated_data = resource.getString("associated_data");
			String nonce =  resource.getString("nonce");
			String ciphertext = resource.getString("ciphertext");
			PayInfo payInfo = payInfoService.findByStreetNo(streetNo);
			AesUtil aesUtils = new AesUtil(payInfo.getV3Key().getBytes());
			String string = aesUtils.decryptToString(associated_data.getBytes(),nonce.getBytes(),ciphertext);
			LOGGER.info("pay info:{},{}",JSONObject.toJSONString(payInfo),string);
			JSONObject jsonObject = JSONObject.parseObject(string);
			//获取订单号
			String payId = jsonObject.getString("out_trade_no");
			//获取支付的订单状态, SUCCESS(支付成功)
			String trade_state = jsonObject.getString("trade_state");
			//获取支付状态  SUCCESS
			if(trade_state.equals("SUCCESS")){
				OrderInfo orderInfo = orderInfoService.getByOrderNo2(payId);
				String orderNo = orderInfo.getOrderNo();
				String success_time = jsonObject.getString("success_time");
				DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");  //yyyy-MM-dd'T'HH:mm:ss.SSSZ
				SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
				String paytime = format.format(df.parse(success_time));
				JSONObject amountObj = jsonObject.getJSONObject("amount");
				String am = amountObj.getString("total");
				if(StringUtil.isBlank(am)) {
					am = "0";
				}
				Double amount = Double.valueOf(am)/100;
				if(orderInfo.getType()==1){
					updateByStatus(streetNo, payId, amount, orderInfo.getMonth(), orderInfo.getCph(),paytime);
				}else{
					updatePayState(payId,paytime,String.valueOf(amount),orderNo);
				}
				LOGGER.info("weapp msg:支付成功");
			}else {
				LOGGER.info("weapp msg:支付失败");
			}
		} catch (Exception e) {
			LOGGER.error("e:{}",e);
		}
		return resp;
	}
	
	/**
	 * 通联后台回调通知
	 * @return
	 */
	@RequestMapping(path = "/uninotice")
	@ResponseBody
	public Resp gNotic(String trxid,String paytime,String trxamt) {
		try {
			trxid = URLDecoder.decode(trxid, "UTF-8");
			paytime = URLDecoder.decode(paytime, "UTF-8");
			trxamt = URLDecoder.decode(trxamt, "UTF-8");
			LOGGER.warn("unipay msg:{},{},{}",trxid,trxamt,trxid);
			OrderInfo orderInfo = orderInfoService.getByOutNo(trxid);
			String orderNo = orderInfo.getOrderNo();
			LOGGER.warn("unipay order no:{},",orderNo);
			String am = trxamt;
			if(StringUtil.isBlank(am)) {
				am = "0";
			}
			Double amount = Double.valueOf(trxamt)/100;
			if(orderInfo.getType()==1){
				updateByStatus(orderInfo.getStreetNo(), trxid, amount, orderInfo.getMonth(), orderInfo.getCph(),paytime);
			}else{
				updatePayState(trxid,paytime,String.valueOf(amount),orderNo);
			}
		} catch (Exception e) {
			LOGGER.error("e:{}",e);
			return new Resp(true);
		}
		return new Resp(true);
	}
	
	
	/**
	 * 拉卡拉支付后台回调通知
	 * @param request
	 * @return
	 */
	@RequestMapping(path = "/data/notice")
	@ResponseBody
	public Resp getNotic(HttpServletRequest request) {
		try {
			DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");  //yyyy-MM-dd'T'HH:mm:ss.SSSZ
			SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
			String json = getRequestJsonString(request);
			LOGGER.warn("lakala msg:{}",json);
			JSONObject obj = JSONObject.parseObject(json);
			String lakalaOrderId = obj.getString("lklOrderNo");
			OrderInfo orderInfo = orderInfoService.getByOutNo(lakalaOrderId);
			String payTime = obj.getString("payTime");
			Date  date = df.parse(payTime);
			String orderNo = obj.getString("merchantOrderNo").split("_")[0];
			String am = obj.getString("amount");
			if(StringUtil.isBlank(am)) {
				am = "0";
			}
			Double amount = Double.valueOf(am)/100;
			if(orderInfo.getType()==1){
				updateByStatus(orderInfo.getStreetNo(), lakalaOrderId, amount, orderInfo.getMonth(), orderInfo.getCph(),format.format(date));
			}else{
				updatePayState(lakalaOrderId,format.format(date),String.valueOf(amount),orderNo);
			}
		} catch (Exception e) {
			LOGGER.error("e:{}",e);
			return new Resp(true);
		}
		return new Resp(true);
	}
	
	
	
	/**
	 * 拉卡拉支付成功回调
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(path = "/data/getServerInfo")
	@ResponseBody
	public Resp getServerInfo(String out_order_no) throws IOException{
		try {
			return new Resp(DATA_MAP.get(out_order_no));
		} catch (Exception e) {
			LOGGER.error("e:{}",e);
		}
		return new Resp(true);
	}
	
	/**
	 * 拉卡拉支付成功回调
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(path = "/data/updatePayStatus")
	@ResponseBody
	public Resp updatePayStatus(String out_order_no,String pay_time,String pay_amount,String order_no) throws IOException{
		try {
			Double am = 0.0;
			if(StringUtil.isNotBlank(pay_amount)) {
				am = Double.valueOf(pay_amount);
			}
			updatePayState(out_order_no,pay_time,String.valueOf(am),order_no);
		} catch (Exception e) {
			LOGGER.error("e:{}",e);
		}
		return new Resp(true);
	}
	
	


	// https://i.lakala.com/doc/openapi/index.html#demo%E6%96%87%E4%BB%B6%E4%B8%8B%E8%BD%BD
		/**
		 * 拉卡拉订单加密
		 * 
		 * @param appId
		 * @param serialNo
		 * @param timestamp
		 * @param nonce
		 * @param reqBody
		 * @param profile
		 * @return
		 * @throws Exception
		 */
		@SuppressWarnings("resource")
		private static String sign(String appId, String serialNo, String timestamp, String nonce, String reqBody,
				String profile) throws Exception {
			String preSignData = appId + "\n" + serialNo + "\n" + timestamp + "\n" + nonce + "\n" + reqBody + "\n";
			//System.out.println("准备加签名的数据：" + preSignData);
			java.security.Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
			String privateKeyFile = KEY_FILE;
			byte[] bytes = new byte[1024];
			int length = 0;
			StringBuffer sb = new StringBuffer();
			File file = new File(privateKeyFile);
			InputStream inputStream = new FileInputStream(file);
			while ((length = inputStream.read(bytes)) != -1) {
				sb.append(new String(bytes, 0, length));
			}
			String privatekeyStr = sb.toString().replace("-----BEGIN RSA PRIVATE KEY-----", "")
					.replace("-----END RSA PRIVATE KEY-----", "").replace("\n", "");
			String signature = RSAUtil.signByPrivateKey(preSignData.getBytes("utf-8"), privatekeyStr);
			return signature;
		}

	
	/**
	 * 拉卡拉退款
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(path = "/data/lakalaRefund")
	@ResponseBody
	public JSONObject lakalaRefund(String outOrderNo,String amount,String tradeNo,String streetNo) throws IOException{
		try {
			PayInfo payInfo = payInfoService.findByStreetNo(streetNo);
			String lakalamerid = payInfo.getMerId();
			String lakalaclientid = payInfo.getClientId();
			String appId = payInfo.getAppId();
			String serialNo = payInfo.getSerialNo();
			Double am = 0.0;
			if(StringUtil.isNotBlank(amount)) {
				am = Double.valueOf(amount);
			}
			String reqData = "{\"reqData\":{\"mercId\":\""+lakalamerid+"\",\"lklOrderNo\":\""+outOrderNo+"\",\"termNo\":\""+lakalaclientid+"\",\"refundOrderId\":\""+tradeNo+"\",\"amount\":\""+am.intValue()+"\"},\"ver\":\"1.0.0\",\"termExtInfo\":{}}";
			String timestamp = String.valueOf((int) (System.currentTimeMillis() / 1000));
			String nonce = StringUtil.generateString(12);
			String signature = sign(appId, serialNo, timestamp, nonce, reqData, "sit");
			String schema = "LKLAPI-SHA256withRSA-AES128";// 双向认证同时对body加密传输
			String token = "appid=\"" + appId + "\",serial_no=\"" + serialNo + "\",timestamp=\"" + timestamp
					+ "\",nonce_str=\"" + nonce + "\",signature=\"" + signature + "\"";
			String header = schema + " " + token;
			LOGGER.warn("lalaka order req:\n{}", reqData);
			String res = HttpUtils.postJsonWithHeader(LAKALA_ORDER_DEL, reqData, header);
			return JSONObject.parseObject(res);
		} catch (Exception e) {
			LOGGER.error("e:{}",e);
		}
		return new JSONObject();
	}
	
	
	/**
	 * 查询待支付金额
	 * @param cph
	 * @param orderNo
	 * @param data
	 * @return
	 */
	@RequestMapping(path = "/data/getCouponMoney")
	public Resp getCouponMoney(String cph,String orderNo,String data){
		Resp resp = new Resp(false);
		try {
			LOGGER.info("获取待支付金额：闸机:{},{},{}",cph,orderNo,data);
			String[] datas = data.split("_");
			Map<String, Object> map = new HashMap<String, Object>();
			Map<String, Object> reqMap = new HashMap<String, Object>();
			List<CouponOrderModel> list = new ArrayList<CouponOrderModel>();
			reqMap.put("carLicense", cph);
			reqMap.put("orderNo", orderNo);
			for(int i =  0;i<datas.length;i++) {
				if(StringUtil.isNotBlank(datas[i])) {
					CouponOrderModel m = new CouponOrderModel();
					m.setCouponId(datas[i]);
					list.add(m);
				}
			}
			reqMap.put("data", list);
			map.put("attr", reqMap);
			try {
				String resStr = HttpUtils.postJson(BASE_URL+GET_COUPON_MONEY_URL,JSONObject.toJSONString(map));
				JSONObject obj = JSONObject.parseObject(resStr);
				String money = obj.getJSONObject("attr").getString("payMoney");
				return new Resp(money);
			} catch (Exception e1) {
				LOGGER.error("获取待支付金额异常e1：{}",e1);
				return new Resp("-1");
			}
		} catch (Exception e) {
			LOGGER.error("获取待支付金额异常：{}",e);
		}
		return resp;
	}
	
	/**
	 * 获取全部优惠券
	 * @param cph
	 * @param parkNo
	 * @return
	 */
	@RequestMapping(path = "/data/getCouponList")
	public Resp getCouponList(String cph,String parkNo){
		Resp resp = new Resp(false);
		try {
			LOGGER.info("获取优惠券列表:{},{}",cph,parkNo);
			Map<String, Object> map = new HashMap<String, Object>();
			Map<String, Object> reqMap = new HashMap<String, Object>();
			if(StringUtil.isNotBlank(parkNo)) {
				reqMap.put("streetNo", parkNo);
			}
			reqMap.put("carLicense", cph);
			map.put("attr", reqMap);
			String resStr = HttpUtils.postJson(BASE_URL+GET_COUPON_URL,JSONObject.toJSONString(map));
			JSONObject res = JSONObject.parseObject(resStr);
			Integer status = res.getInteger("status");
			if(status==0) {
				JSONArray arr = res.getJSONObject("blocks").getJSONObject("msg").getJSONArray("rows");
				List<CouponModel> list = new ArrayList<CouponModel>();
				for(int i = 0;i<arr.size();i++) {
					JSONArray objArr = arr.getJSONArray(i);
					String type = objArr.getString(2);
					CouponModel model = new CouponModel();
					model.setCouponId(objArr.getString(6));
					model.setCouponType(type);
					model.setCouponDescribe(objArr.getString(10));
					model.setCouponInde(objArr.getString(7));
					model.setCouponMoney(objArr.getString(3));
					model.setCouponUnInde(objArr.getString(9));
					list.add(model);
				}
				return new Resp(list);
			}
		} catch (Exception e) {
			LOGGER.error("获取优惠券异常：{}",e);
		}
		return resp;
	}
	
	/**
	 * 支付成功回调
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(path = "/data/getOrderByLakala")
	@ResponseBody
	public Resp getOrderByLakala(String out_order_no,String order_no,String streetNo,String _type,String _month,String cph) throws IOException{
		try {
			PayInfo payInfo = payInfoService.findByStreetNo(streetNo);
			if(payInfo!=null&&"allinpay".equals(payInfo.getPayMethod())) {
				OrderInfo orderInfo = orderInfoService.getByOrderNo(order_no);
				updatePayState(out_order_no,"",String.valueOf(orderInfo.getPay()) ,order_no);
			}else if(payInfo!=null&&"lakala".equals(payInfo.getPayMethod())){
				String lakalamerid = payInfo.getMerId();
				String lakalaclientid = payInfo.getClientId();
				String appId = payInfo.getAppId();
				String serialNo = payInfo.getSerialNo();
				LOGGER.warn("lalaka order_no {},{} ", out_order_no,order_no);
				String reqData = "{\"reqData\":{\"mercId\":\""+lakalamerid+"\",\"lklOrderNo\":\""+out_order_no+"\",\"termNo\":\""+lakalaclientid+"\"},\"ver\":\"1.0.0\",\"termExtInfo\":{}}";
				String timestamp = String.valueOf((int) (System.currentTimeMillis() / 1000));
				String nonce = StringUtil.generateString(12);
				String signature = sign(appId, serialNo, timestamp, nonce, reqData, "sit");
				String schema = "LKLAPI-SHA256withRSA-AES128";// 双向认证同时对body加密传输
				String token = "appid=\"" + appId + "\",serial_no=\"" + serialNo + "\",timestamp=\"" + timestamp
						+ "\",nonce_str=\"" + nonce + "\",signature=\"" + signature + "\"";
				String header = schema + " " + token;
				LOGGER.warn("lalaka order req:\n{}", reqData);
				String res = HttpUtils.postJsonWithHeader(LAKALA_ORDER_SELECT, reqData, header);
				JSONObject obj = JSONObject.parseObject(res);
				JSONObject respData = obj.getJSONObject("respData");
				String tradeState = respData.getString("tradeState");
				if("SUCCESS".equals(tradeState)) {
					String pay_time = respData.getString("payTime");
					order_no = "";
					LOGGER.warn("amount:{}",respData.getString("amount"));
					Double pay_amount = Double.valueOf( respData.getString("amount"))/100;
					if(StringUtil.isNotBlank(_type)&&"GZ".equals(_type)) {
						LOGGER.warn("包月回调:{}");
						updateByStatus(streetNo,out_order_no,pay_amount,_month,cph,pay_time);
					}else {
						updatePayState(out_order_no,pay_time,String.valueOf(pay_amount) ,order_no);
					}
				}
				return new Resp(respData);
			}
			
		} catch (Exception e) {
			LOGGER.error("e:{}",e);
		}
		return new Resp(true);
	}
	
	/**
	 * 获取可用优惠券
	 * @param cph
	 * @param parkNo
	 * @return
	 */
	@RequestMapping(path = "/data/getCouponListAble")
	public Resp getCouponListAble(String cph,String parkNo){
		Resp resp = new Resp(false);
		try {
			LOGGER.info("获取可用优惠券:{},{}",cph,parkNo);
			Map<String, Object> map = new HashMap<String, Object>();
			Map<String, Object> reqMap = new HashMap<String, Object>();
			if(StringUtil.isNotBlank(parkNo)) {
				reqMap.put("streetNo", parkNo);
			}
			reqMap.put("carLicense", cph);
			map.put("attr", reqMap);
			String resStr = HttpUtils.postJson(BASE_URL+GET_COUPON_URL_ABLE,JSONObject.toJSONString(map));
			JSONObject res = JSONObject.parseObject(resStr);
			Integer status = res.getInteger("status");
			if(status==0) {
				JSONArray arr = res.getJSONObject("blocks").getJSONObject("msg").getJSONArray("rows");
				List<CouponModel> list = new ArrayList<CouponModel>();
				for(int i = 0;i<arr.size();i++) {
					JSONArray objArr = arr.getJSONArray(i);
					String type = objArr.getString(2);
					CouponModel model = new CouponModel();
					model.setCouponId(objArr.getString(6));
					model.setCouponType(type);
					model.setCouponDescribe(objArr.getString(10));
					model.setCouponInde(objArr.getString(7));
					model.setCouponMoney(objArr.getString(3));
					model.setCouponUnInde(objArr.getString(9));
					model.setTime(objArr.getString(5));
					list.add(model);
				}
				return new Resp(list);
			}
		} catch (Exception e) {
			LOGGER.error("获取可用优惠券异常：{}",e);
		}
		return resp;
	}
	
	/**
	 * 包月车查询
	 * @return
	 */
	@RequestMapping(path = "/data/getByInfo")
	public Resp getByInfo(String carLicense,String openid,Integer type){
		Resp resp = new Resp(false);
		try {
			LOGGER.info("获取包月信息：{},{},{}",carLicense,openid,type);
			Map<String,Object> map = new HashMap<String, Object>();
			Map<String,Object> data = new HashMap<String, Object>();
			data.put("carLicense", carLicense);
			map.put("attr", data);
			String res = HttpUtils.postJson(BASE_URL+BY_INFO_URL,JSONObject.toJSONString(map));
			if(StringUtil.isNotBlank(openid)) {
				UserInfo user = userInfoService.findBySAndOAndC(openid, carLicense,"",type);
				if(user==null) {
					user = new UserInfo();
					user.setCph(carLicense);
					user.setCreateTime(new Date());
					user.setOpenid(openid);
					user.setType(type);
					user.setStreetNo("");
					userInfoService.save(user);
				}else {
					user.setCreateTime(new Date());
					userInfoService.update(user);
				}
			}
			return new Resp(JSONObject.parseObject(res));
		} catch (Exception e) {
			LOGGER.error("e:{}",e);
		}
		return resp;
	}
	
	/**
	 * 获取发票链接
	 * @param orderNo
	 * @return
	 */
	@RequestMapping(path = "/data/getInvoice")
	public Resp getInvoice(String orderNo){
		Resp resp = new Resp(false);
		try {
			LOGGER.info("获取发票链接:{}",orderNo);
			Map<String, Object> map = new HashMap<String, Object>();
			Map<String, String> data = new HashMap<String, String>();
			data.put("orderNo", orderNo);
			map.put("attr", data);
			String json = JSONObject.toJSONString(map);
			String res = HttpUtils.postJson(BASE_URL+INVOICE_URL,json );
			return new Resp(JSONObject.parseObject(res));
		} catch (Exception e) {
			LOGGER.error("e:{}",e);
		}
		return resp;
	}
	

	/**
	 * 根据车牌查询所有停车记录
	 * 
	 * @param carLicense
	 * @return
	 */
	@RequestMapping(path = "/data/getRecords")
	public HttpResult queryParkingRecordsByCarLicense(String carLicense) {
		HttpResult hr = new HttpResult();
		try {
			hr.setSuccess(false);
			Map<String, Object> map = new HashMap<String, Object>();
			Map<String, String> data = new HashMap<String, String>();
			data.put("carLicense", carLicense);
			map.put("attr", data);
			String json = JSONObject.toJSONString(map);
			String result = HttpUtils.postJson(BASE_URL + ALL_PARK_RECORD, json);
			JSONObject jsonObject = JSONObject.parseObject(result);
			if ("0".equals(jsonObject.getString("status"))) {
				List<ParkingRecordDto> dtos = new ArrayList<>();
				String jo = jsonObject.getJSONObject("blocks").getJSONObject("parkingRecords").getString("rows");
				if(jo!=null) {
					JSONArray jsonArray = JSONObject.parseArray(jo);
					LOGGER.info("queryParkingRecordsByCarLicense ====>" + jsonArray);
					for (int i = 0; i < jsonArray.size(); i++) {
						JSONArray array = jsonArray.getJSONArray(i);
						ParkingRecordDto recordDto = new ParkingRecordDto();
						// 订单号
						recordDto.setOrderNo((String) array.get(1));
						// 应付金额
						recordDto.setShouldPayMoney((String) array.get(2));
						// 场库编号
						recordDto.setStreetNo((String) array.get(3));
						// 停车时长
						recordDto.setParkingTime((String) array.get(5));
						// 进场时间
						recordDto.setInTime(DateFormatUtils.subTimestampStr3((String) array.get(6)));
						// 出场时间
						recordDto.setOutTime(DateFormatUtils.subTimestampStr3((String) array.get(7)));
						// 实付金额
						recordDto.setPayMoney((String) array.get(8));
						recordDto.setSreetName((String) array.get(0));
						// 车牌号
						recordDto.setCarLicense(carLicense);
						dtos.add(recordDto);
					}
					hr.setSuccess(true);
					hr.setResult(dtos);
				}else {
					hr.setSuccess(false);
				}
			}
		} catch (Exception e) {
			LOGGER.error("e:{}",e);
		}
		return hr;
	}

	/**
	 * 获取计费规则
	 * 
	 * @param streetNo
	 * @return
	 */
	@RequestMapping(path = "/data/getFeeRole")
	public HttpResult getFellRole(String streetNo) {
		Map<String, String> map = new HashMap<String, String>();
		Map<String, Object> data = new HashMap<String, Object>();
		if (StringUtil.isBlank(streetNo)||"null".equals(streetNo)) {
			streetNo = "ZKZJ001";
		}
		map.put("streetNo", streetNo);
		data.put("attr", map);
		String result = HttpUtils.postJson(BASE_URL + PAY_ROLE, JSONObject.toJSONString(data));
		JSONObject jsonObject = JSONObject.parseObject(result);
		// System.out.println(jsonObject);
		HttpResult hr = new HttpResult();
		hr.setSuccess(false);
		if ("0".equals(jsonObject.getString("status"))) {
			JSONObject attr = jsonObject.getJSONObject("attr");
			BillingRulesDto rulesDto = new BillingRulesDto();
			rulesDto.setPriceNo(attr.getString("priceNo"));
			// 第一个计费时长（秒）
			int firstPeriod = Integer.parseInt(attr.getString("firstPeriod"));
			rulesDto.setFirstPeriod(Double.toString(firstPeriod / 3600.0));
			// 第一个计费时长费用
			rulesDto.setFirstPeriodMoney(attr.getString("firstperiodMoney"));
			// 超过免费停放时长后，免费时长是否收费（0、不收费 1、收费）
			rulesDto.setOverFreeIfMoney(attr.getString("overfreeIfmoney"));
			// 超过免费停放时长之后的单位计费时长（秒）
			int periodTime = Integer.parseInt(attr.getString("periodTime"));
			rulesDto.setPeriodTime(Double.toString(periodTime / 3600.0));
			// 超过免费停放时长之后的单位计费时长收费金额（元）
			rulesDto.setPeriodMoney(attr.getString("periodMoney"));
			// 免费停放时长（秒）
			int freeParkingTime = Integer.parseInt(attr.getString("freeparkingTime"));
			rulesDto.setFreeParkingTime(Double.toString(freeParkingTime / 3600.0));
			// 超过免费停放时长后，免费时长是否收费（0、不收费 1、收费）
			rulesDto.setOverFreeIfMoney(attr.getString("overfreeIfmoney"));
			// 超过免费停放时长之后的单位计费时长收费金额（元）
			rulesDto.setPeriodMoney(attr.getString("periodMoney"));
			// 每24小时内收费上线（元）
			rulesDto.setMaxDayMoney(attr.getString("maxDaymoney"));
			// 不足停车计费时间的处理方式（1舍去、2补足、3过半补足）
			rulesDto.setCompletionMethod(attr.getString("completionMethod"));
			// 节假日是否免费（0、不免费 1、免费）
			rulesDto.setHolidayFree(attr.getString("holidayFree"));
			// 工作日是否免费（0、不免费 1、免费）
			rulesDto.setWorkdayFree(attr.getString("workdayFree"));
			hr.setSuccess(true);
			hr.setResult(rulesDto);
		}
		return hr;

	}

	/**
	 * 
	 * 查询在停订单
	 * 
	 * @param cph
	 * @param
	 * @return
	 */
	@RequestMapping(path = "/data/selectOrderByCphAndStreetNo")
	@ResponseBody
	public HttpResult selectOrderByCphAndStreetNo(String cph,String openid,Integer type) {
		HttpResult httpResult = new HttpResult(false);
		try {
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			Map<String, Object> attrJson = new HashMap<String, Object>();
			attrJson.put("carLicense", cph);
			Map<String, Object> reqJson = new HashMap<String, Object>();
			reqJson.put("attr", attrJson);
			String result = HttpUtils.postJson(BASE_URL + SELECT_ZJ_ORDER, JSONObject.toJSONString(reqJson));
			if (StringUtil.isNotBlank(result)) {
				JSONObject order = JSONObject.parseObject(result);
				HttpResult hr = new HttpResult();
				if ((1 != order.getInteger("status"))) {
					hr.setSuccess(false);
					hr.setMsg(order.getString("msg"));
					return hr;
				}
				JSONObject orderMap = order.getJSONObject("attr").getJSONObject("orderMap");
				OrderDto dto = new OrderDto();
				dto.setCarLicense(orderMap.getString("carLicense"));
				dto.setDuration(orderMap.getString("duration"));
				String realCost = orderMap.getString("realMoney");
				dto.setHavePayMoney(new BigDecimal(StringUtil.isBlank(realCost) ? "0.00" : realCost));
				dto.setInTime(DateFormatUtils.subTimestampStr3(orderMap.getString("startTime")));
				dto.setOutTime(DateFormatUtils.subTimestampStr3(orderMap.getString("endTime")));
				String payableCost = orderMap.getString("payableMoney");
				String orderMoney = orderMap.getString("orderMoney");
				dto.setShouldPayMoney(new BigDecimal(StringUtil.isBlank(orderMoney) ? "0.00" : orderMoney));
				dto.setShouldPayMoney1(new BigDecimal(StringUtil.isBlank(payableCost) ? "0.00" : payableCost));
				dto.setOrderNo(orderMap.getString("orderNo"));
				dto.setStreetNo(orderMap.getString("streetNo"));
				dto.setParkingTimes(orderMap.getString("parkingTime"));
				hr.setSuccess(true);
				hr.setResult(dto);
				hr.setMsg(order.getString("msg"));
				hr.setMsg(format.format(new Date()));
				if(StringUtil.isNotBlank(openid)) {
					UserInfo user = userInfoService.findBySAndOAndC(openid, cph, dto.getStreetNo(),type);
					if(user==null) {
						user = new UserInfo();
						user.setCph(cph);
						user.setCreateTime(new Date());
						user.setOpenid(openid);
						user.setStreetNo( dto.getStreetNo());
						userInfoService.save(user);
					}else {
						user.setCreateTime(new Date());
						userInfoService.update(user);
					}
				}
				return hr;
			}
		} catch (Exception e) {
			LOGGER.error("select order by cph and streetno err:{}", e);
		}
		return httpResult;
	}


	
	/**
	 * 
	 * @param streetNo
	 * @param out_order_no
	 * @param _month
	 * @param pay_time 
	 */
	private void updateByStatus(String streetNo, String out_order_no, Double payMoney, String _month,String cph, String pay_time) {
		try {
			Map<String, Object> map = new HashMap<String, Object>();
			Map<String, Object> data = new HashMap<String, Object>();
			data.put("nums", _month);
			data.put("streetNo", streetNo);
			data.put("carLicense", cph);
			data.put("tradeOwner", "lakala");
			data.put("payMoney", String.valueOf(payMoney));
			data.put("payMethod", "weChat");
			data.put("tradeTime",pay_time);
			data.put("outOrderNo",out_order_no );
			map.put("attr", data);
			HttpUtils.postJson(BASE_URL+BY_CALL_BACK, JSONObject.toJSONString(map));
		} catch (Exception e) {
			LOGGER.error("e:{}",e);
		}
	}


	/**
	 * 推送回调结果
	 * @param out_order_no
	 * @param pay_time
	 * @param pay_amount
	 * @param order_no
	 * @return
	 */
	public JSONObject updatePayState(String out_order_no,String pay_time,String pay_amount,String order_no) {
		LOGGER.warn("{},{},{},{}",out_order_no,pay_time,pay_amount,order_no);
		Double am = 0.0;
		if(StringUtil.isNotBlank(pay_amount)) {
			am = Double.valueOf(pay_amount);
		}
		Map<String, Object> map = new HashMap<String, Object>();
		Map<String, Object> data = new HashMap<String, Object>();
		data.put("out_order_no", out_order_no);
		data.put("order_no", order_no);
		data.put("pay_interface_no", "WECHAT");
		data.put("pay_amount", String.valueOf(am));
		data.put("pay_time", pay_time);
		map.put("attr", data);
		String res = HttpUtils.postJson(BASE_URL+PAY_CALL_BACK, JSONObject.toJSONString(map));
		return JSONObject.parseObject(res);
		
	}
	
	
}
